package com.swak.def_method;

import java.io.Serializable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class AProxy implements InvocationHandler, Serializable {

	private static final long serialVersionUID = 1L;

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("反射执行");

		if (method.isDefault()) {
			System.out.println("执行默认方法");

			if (sayMethodHandle == null) {
				Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class
						.getDeclaredConstructor(Class.class, int.class);
				constructor.setAccessible(true);

				Class<?> declaringClass = method.getDeclaringClass();
				int allModes = MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE
						| MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE;

				sayMethodHandle = constructor.newInstance(declaringClass, allModes)
						.unreflectSpecial(method, declaringClass).bindTo(proxy);
			}
			return sayMethodHandle.invokeWithArguments(args);
		}

		System.out.println("执行接口方法");
		return "Hello Say2";
	}

	private MethodHandle sayMethodHandle;

}
